延續昨天的主題,已經建好action 需要用到的message以後,就可以寫action server
和action client
進行任務的處理囉! 本次都以c++為範例,python版的請參考官網。
在編譯完昨天的message後,在client和server端都可以進行呼叫。
client:
1 #include <chores/DoDishesAction.h> // Note: "Action" is appended
2 #include <actionlib/client/simple_action_client.h>
3
4 typedef actionlib::SimpleActionClient<chores::DoDishesAction> Client;
5
6 int main(int argc, char** argv)
7 {
8 ros::init(argc, argv, "do_dishes_client");
9 Client client("do_dishes", true); // true -> don't need ros::spin()
10 client.waitForServer();
11 chores::DoDishesGoal goal;
12 // Fill in goal here
13 client.sendGoal(goal);
14 client.waitForResult(ros::Duration(5.0));
15 if (client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
16 printf("Yay! The dishes are now clean");
17 printf("Current State: %s\n", client.getState().toString().c_str());
18 return 0;
19 }
其實還蠻直觀的,就是宣告一個client物件以後讓他跟server交握,之後送指令過去,並以每秒5次的頻率等待結果直到完成洗碗的動作。
server:
1 #include <chores/DoDishesAction.h> // Note: "Action" is appended
2 #include <actionlib/server/simple_action_server.h>
3
4 typedef actionlib::SimpleActionServer<chores::DoDishesAction> Server;
5
6 void execute(const chores::DoDishesGoalConstPtr& goal, Server* as) // Note: "Action" is not appended to DoDishes here
7 {
8 // Do lots of awesome groundbreaking robot stuff here
9 as->setSucceeded();
10 }
11
12 int main(int argc, char** argv)
13 {
14 ros::init(argc, argv, "do_dishes_server");
15 ros::NodeHandle n;
16 Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
17 server.start();
18 ros::spin();
19 return 0;
20 }
server端則是定義好會被呼叫的API以後執行server等待API被呼叫,跟service 的server蠻像的。
今天時間有點不夠用,真是抱歉QQQQQ 社畜上班族筆者之後會找時間再回來把程式碼的部分好好解析的,若有需要的話可以參考reference內的api文件。
https://docs.ros.org/api/actionlib/html/classactionlib_1_1SimpleActionClient.html#a94b5a38fae6917f83331560b81eea341
https://docs.ros.org/api/actionlib/html/classactionlib_1_1SimpleActionServer.html